const defaults = {
    timeout:0
}
class Axios {
    constructor(instanceConfig={}) {
        this.defaults = instanceConfig
    }
    request(configOrUrl={},config={}){
        if(typeof configOrUrl === "string"){
            config.url = configOrUrl;
        }else config = configOrUrl;

        config = {
            ...this.defaults,
            ...config
        }
        config.method = (config.method || "get").toLowerCase();
        const {headers={}} = config;
        if(config.baseURL && !config.url.startsWith("http://")){
            config.url = config.baseURL+config.url;
        }
        if(config.params){
            config.url = config.url+"?"+Object.keys(config.params).map(key=>key+"="+config.params[key]).join("&")
        }
        const _dispatchRequest = function(){
            return new Promise(function(resolve,reject){
                const request = new XMLHttpRequest();
                request.responseType = "json";
                request.timeout = config.timeout;
                request.open(config.method,config.url);
                for(let key in headers){
                    request.setRequestHeader(key,headers[key])
                }
                if(config.data){
                    if(typeof config.data === "object"){
                        request.setRequestHeader("Content-Type","application/json");
                        config.data = JSON.stringify(config.data);
                    }else{
                        request.setRequestHeader("Content-Type","application/x-www-form-urlencoded")
                    }
                }
                request.send(config.data);
                request.onload = function(){
                    if(request.status>=200 && request.status<300){
                        resolve({
                            config,
                            data:request.response,
                            headers:request.getAllResponseHeaders(),
                            request,
                            status:request.status,
                            statusText:request.statusText
                        })
                    }else{
                        reject({
                            code:"my-ERR_BAD_REQUEST",
                            config,
                            request,
                            status:request.status
                        })
                    }

                }
                request.ontimeout = function(){
                    reject({
                        code:"ECONNABORTED",
                        config,
                        message:"timeout of "+config.timeout+"ms exceeded",
                        name:"AxiosError",
                        request
                    })
                };
                request.onerror = function(){
                    reject({
                        code:"ERR_NETWORK"
                    })
                }
            })

        }
        return _dispatchRequest();
    }
}
function createInstance(defaultConfig){
    const context = new Axios(defaultConfig);
    const instance = Axios.prototype.request.bind(context);
    for(let key in context){
        instance[key] = context[key];
    }
    return instance;
}
const axios = createInstance(defaults);
export default axios;